import { throttle } from './utils';

export default function scroller(selector) {
    if (selector.nodeType) {
        return new Scroller(selector);
    }
    const $el = document.querySelector(selector);
    return new Scroller($el);
}

function scrollable($el) {
    return $el.scrollHeight > $el.clientHeight;
}

const resize = throttle(function() {
    const resize = this.contentHeight !== this.$content.offsetHeight;
    resize && this.update();
}, 100);

export class Scroller {
    constructor($el) {
        this.$el = $el;
        this.distance = {
            x: 0,
            y: 0
        };
        this.create();
        this.resize = resize;
    }

    disable() {
        this.$el.classList.add('disabled');
    }

    enable() {
        this.$el.classList.remove('disabled');
    }

    create() {
        let oriHtml = this.$el.innerHTML;
        this.width = this.$el.offsetWidth;

        this.$content = this.$el.querySelector('.z-scroller-content');

        if (this.$content) {
            oriHtml = this.$content.innerHTML;
        }

        const nextHtml = `
      <div class="z-scroller-box">
        <div class="z-scroller-content" style="width: ${this.width}px">
          ${oriHtml}
        </div>
      </div>
      <div class="z-scroller-bar">
        <div class="z-scroller-chunk"></div>
      </div>
    `;

        this.$el.innerHTML = nextHtml;
        this.$el.classList.add('z-scroller');

        this.$bar = this.$el.querySelector('.z-scroller-bar');
        this.$box = this.$el.querySelector('.z-scroller-box');
        this.$chunk = this.$el.querySelector('.z-scroller-chunk');
        this.$content = this.$el.querySelector('.z-scroller-content');

        this.update();

        window.addEventListener('resize', throttle(() => this.update(), 100));

        this.$box.addEventListener('scroll', () => {
            this.updateChunkPosition({
                x: this.$box.scrollTop
            });
            this.resize();
        });

        this.$chunk.addEventListener('mousedown', event => {
            this.holdChunk = true;
            this.mouse = {
                x: event.clientX,
                y: event.clientY
            };
            document.addEventListener('selectstart', this.preventSelect);
        });

        document.addEventListener('mousemove', event => {
            if (this.holdChunk) {
                const { clientX, clientY } = event;
                this.scrollContent({
                    x: (clientX - this.mouse.x) / this.scale,
                    y: (clientY - this.mouse.y) / this.scale
                });
                this.mouse = {
                    x: clientX,
                    y: clientY
                };
            }
        });

        document.addEventListener('mouseup', () => {
            this.holdChunk = false;
            this.mouse = {};
            document.removeEventListener('selectstart', this.preventSelect);
        });
    }

    update() {
        this.height = this.$el.offsetHeight;
        this.contentHeight = this.$content.offsetHeight;
        this.width = this.$el.offsetWidth;

        // 有时会有1px的误差
        this.$content.style.width = this.width + 1 + 'px';
        this.chunkHeight = (this.height / this.contentHeight) * this.height;
        this.$chunk.style.height = this.chunkHeight + 'px';
        this.scale =
            (this.height - this.chunkHeight) /
            (this.contentHeight - this.height);
        if (this.height >= this.contentHeight) {
            this.$el.classList.add('no-scroll');
        } else {
            this.$el.classList.remove('no-scroll');
        }
        // this.$el.addEventListener('mouseover', this.preventOuterScroller);
        // this.$el.addEventListener('mouseout', this.enableOuterScroller);
    }

    scrollContent(distance) {
        const scrollTop = this.$box.scrollTop;
        this.$box.scrollTop = scrollTop + distance.y;
    }

    updateChunkPosition(distance) {
        this.distance.x += distance.x;
        this.distance.y += distance.y;
        this.$chunk.style.transform = this.$chunk.style.webkitTransform = `translate3d(0, ${distance.x *
            this.scale}px, 0)`;
    }

    preventSelect(event) {
        event.preventDefault();
    }
}
